package cn.com.generaldata.os.service.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.impl.sql.SqlTemplate;
import org.nutz.lang.Mirror;
import org.nutz.lang.random.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.generaldata.jsme_indicator_system.entity.Indicator;
import cn.com.generaldata.jsme_indicator_system.entity.ReportTypeIndicator;
import cn.com.generaldata.jsme_indicator_system.entity.SummaryReportType;
import cn.com.generaldata.jsme_indicator_system.entity.SummaryReportTypeRel;
import cn.com.generaldata.jsme_indicator_system.entity.VerifyReportDetail;
import cn.com.generaldata.jsme_indicator_system.util.Constants.ReportStyle;
import cn.com.generaldata.os.constant.Constants;
import cn.com.generaldata.os.pojo.Area;
import cn.com.generaldata.os.pojo.Unit;
import cn.com.generaldata.os.service.common.AreaService;
import cn.com.generaldata.os.vo.DynamicReportVO;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;

/**
 * 报表汇总service.
 */
@Service
public class SummaryReportService {

	private static final String AREA_ID_KEY = "areaId";
	private static final String AREA_NAME_KEY = "地区名称";

	@Autowired
	private Dao dao;

	@Autowired
	private SqlTemplate sqlTemplate;
	@Autowired
	private UnitService unitService;

	@Autowired
	private AreaService areaService;

	private final Mirror<VerifyReportDetail> mirror = Mirror.me(VerifyReportDetail.class);

	/**
	 * 将查询出来的报表数据转换成数据汇总表形式.
	 * 
	 * @param reportDetails 报表数据详情
	 * @param reportTypeId 汇总表报表id
	 * @param currentUserAreaId 当前用户地区id
	 * @param flag 是否将数据转成树形结果
	 * @return
	 */
	public DynamicReportVO converReportDetail(List<VerifyReportDetail> reportDetails, String reportTypeId,
			String currentUserAreaId, boolean flag) {

		SummaryReportType srt = dao.fetch(SummaryReportType.class, reportTypeId);
		if (srt == null)
			return null;
		DynamicReportVO result = null;
		if (srt.getDataType().intValue() == ReportStyle.CELL.getValue()) {
			result = converCellReportDetail(reportDetails, srt, currentUserAreaId, flag);
		} else {
			result = converRowReportDetail(reportDetails, srt, currentUserAreaId, flag);
		}

		return result;
	}

	/**
	 * 报表与指标信息
	 */
	class ReportIndicatorInfo {
		Map<Integer, Indicator> indicatorMap;
		List<ReportTypeIndicator> rtis;
	}

	/**
	 * 获取报表与指标关系
	 * 
	 * @param srt
	 * @return
	 */
	private ReportIndicatorInfo getReportIndicatorInfo(SummaryReportType srt) {
		ReportIndicatorInfo rii = new ReportIndicatorInfo();

		rii.indicatorMap = getIndicatorMapByReportType(srt.getReportTypeId());

		List<SummaryReportTypeRel> rels = dao.query(SummaryReportTypeRel.class,
				Cnd.where("reportTypeId", "=", srt.getId()));

		Condition cnd = Cnd.where("reportTypeId", "=", srt.getReportTypeId()).asc("row").asc("theColumn");
		if (!rels.isEmpty()) {

			final List<Integer> indicatorIds = Lists.transform(rels, new Function<SummaryReportTypeRel, Integer>() {

				@Override
				public Integer apply(SummaryReportTypeRel input) {
					return input.getIndicatorId();
				}
			});

			List<ReportTypeIndicator> rtis = dao.query(ReportTypeIndicator.class, cnd);

			Collection<ReportTypeIndicator> filterRtis = Collections2.filter(rtis,
					new Predicate<ReportTypeIndicator>() {
						@Override
						public boolean apply(ReportTypeIndicator input) {
							return indicatorIds.contains(input.getIndicatorId());
						}
					});
			rii.rtis = Lists.newArrayList(filterRtis);

		} else {
			rii.rtis = dao.query(ReportTypeIndicator.class, cnd);
		}

		return rii;
	}

	/**
	 * 将单元格式报表详情转换成单行形式.
	 * 
	 * @param reportDetails
	 * @param reportTypeId
	 */
	public DynamicReportVO converCellReportDetail(List<VerifyReportDetail> reportDetails, SummaryReportType srt,
			String currentUserAreaId, boolean flag) {
		ReportIndicatorInfo rii = getReportIndicatorInfo(srt);
		Set<AreaUnitIdReportId> urids = extractUnitId(reportDetails);

		List<Map<String, Object>> table = Lists.newArrayList();
		Table<String, Integer, List<Double>> indicatorValTab = HashBasedTable.create();

		for (final AreaUnitIdReportId urid : urids) {

			Map<String, Object> row = createCellReportRow(reportDetails, rii, indicatorValTab, urid);
			table.add(row);

		}

		addSumRow(currentUserAreaId, rii.indicatorMap, rii.rtis, urids, table, indicatorValTab);
		return transformResult(flag, rii.indicatorMap, rii.rtis, table);
	}

	/**
	 * 转换结果为VO
	 * 
	 * @param flag
	 * @param indicatorMap
	 * @param rtis
	 * @param table
	 * @return
	 */
	private DynamicReportVO transformResult(boolean flag, Map<Integer, Indicator> indicatorMap,
			List<ReportTypeIndicator> rtis, List<Map<String, Object>> table) {
		DynamicReportVO result = new DynamicReportVO();

		List<List<String>> headers = Lists.newArrayList();
		List<String> indicatorNames = getIndicatorNameHeader(indicatorMap, rtis);
		List<String> indicatorUnits = getIndicatorUnitHeader(indicatorMap, rtis);
		headers.add(indicatorNames);
		headers.add(indicatorUnits);
		result.setHeaders(headers);

		// 汇总
		if (flag) {
			result.setBody(table);
		} else {
			result.setBody(converHdataToGdata(table));
		}

		return result;
	}

	/**
	 * 构造表格的头部.
	 * 
	 * @param indicatorMap
	 * @param rtis
	 * @return
	 */
	private List<String> getIndicatorNameHeader(Map<Integer, Indicator> indicatorMap, List<ReportTypeIndicator> rtis) {
		List<String> header = Lists.newArrayList();
		header.add(AREA_NAME_KEY);
		header.add("选择审核");
		header.add("企业编号");
		header.add("企业名称");
		for (ReportTypeIndicator rti : rtis) {
			Indicator indicator = indicatorMap.get(rti.getIndicatorId());
			header.add(indicator.getName() + "/" + indicator.getUnit());
		}

		return header;
	}

	private List<String> getIndicatorUnitHeader(Map<Integer, Indicator> indicatorMap, List<ReportTypeIndicator> rtis) {
		List<String> header = Lists.newArrayList();
		header.add("");
		header.add("选择审核");
		header.add("");
		header.add("");
		for (ReportTypeIndicator rti : rtis) {
			Indicator indicator = indicatorMap.get(rti.getIndicatorId());
			header.add(indicator.getUnit() == null ? "" : indicator.getUnit());
		}

		return header;
	}

	private Map<String, Object> createCellReportRow(List<VerifyReportDetail> reportDetails, ReportIndicatorInfo rii,
			Table<String, Integer, List<Double>> indicatorValTab, final AreaUnitIdReportId urid) {
		Map<String, Object> row = Maps.newLinkedHashMap();
		row.put("选择审核", true);
		row.put("unitId", urid.unitId);
		row.put("reportId", urid.reportId);
		row.put(AREA_ID_KEY, urid.areaId);
		Unit unit = unitService.queryUnitById(urid.unitId);
		row.put("企业编号", unit.getSuperCompanyCode());
		row.put("企业名称", unit.getUnitName());
		row.put(AREA_NAME_KEY, unit.getArea().getAreaName());
		int i = 1;
		for (ReportTypeIndicator rti : rii.rtis) {
			VerifyReportDetail vrd = filterByUnitAndReportAndRow(reportDetails, urid.unitId, urid.reportId,
					rti.getRow());

			String indicatorValue = getIndicatorValue(vrd, rti.getTheColumn());
			Indicator indicator = rii.indicatorMap.get(rti.getIndicatorId());
			//			row.put(indicator.getName(), indicatorValue);
			row.put(indicator.getName() + "/" + indicator.getUnit(), indicatorValue);
			//			row.put(indicator.getUnit() + i, indicatorValue);
			i++;
			if (indicator.getSummarization() == 1) {
				addIndicatorValToTable(indicatorValTab, vrd, indicatorValue, indicator);
			}
		}
		return row;
	}

	/**
	 * 判断是否要加上最后的合计总行，只有市级用户和省级用户才有
	 * 
	 * @param currentUserAreaId
	 * @return
	 */
	private boolean isNeedLastSumRow(String currentUserAreaId) {
		return "00".equals(currentUserAreaId.substring(4, 6)) && !Constants.LSB_AREA_ID.equals(currentUserAreaId);
	}

	/**
	 * 增加指标值到指标数据表中
	 * 
	 * @param indicatorValTab
	 * @param vrd
	 * @param indicatorValue
	 * @param indicator
	 */
	private void addIndicatorValToTable(Table<String, Integer, List<Double>> indicatorValTab, VerifyReportDetail vrd,
			String indicatorValue, Indicator indicator) {
		List<Double> indicatorVals = indicatorValTab.get(vrd.getAeraId(), indicator.getId());
		if (indicatorVals == null) {
			indicatorVals = Lists.newArrayList();
			indicatorValTab.put(vrd.getAeraId(), indicator.getId(), indicatorVals);
		}

		try {
			Double d = Double.valueOf(indicatorValue);
			indicatorVals.add(d);
		} catch (Exception e) {
		}
	}

	/**
	 * 增加总计行
	 */
	private Map<String, Object> addTotalSumRow(String currentAreaId,
			Table<String, Integer, List<Double>> indicatorValTab, List<ReportTypeIndicator> rtis,
			Map<Integer, Indicator> indicatorMap) {
		Area area = areaService.queryAreaById(currentAreaId);
		Map<String, Object> row = Maps.newLinkedHashMap();
		row.put("选择审核", false);
		row.put("企业编号", "");
		row.put("unitId", R.UU16());
		row.put("企业名称", area.getAreaName() + "总计");
		row.put(AREA_NAME_KEY, area.getAreaName());
		row.put(AREA_ID_KEY, area.getId());
		int i = 1;
		for (ReportTypeIndicator rti : rtis) {
			Indicator indicator = indicatorMap.get(rti.getIndicatorId());
			if (indicator.getSummarization() == 1) {
				Collection<List<Double>> indicatorVals = indicatorValTab.column(indicator.getId()).values();
				double indicatorSum = 0;
				for (List<Double> dl : indicatorVals) {
					for (Double d : dl) {
						indicatorSum += d;
					}
				}
				row.put(indicator.getName() + "/" + indicator.getUnit(), String.format("%.2f", indicatorSum));
				//				row.put(indicator.getUnit() + i,);
				//				row.put(indicator.getName(), String.format("%.2f", indicatorSum));
			} else {
				//				row.put(indicator.getName(), "");
				row.put(indicator.getName() + "/" + indicator.getUnit(), "");
			}
			i++;
		}

		return row;

	}

	/**
	 * 增加市级合计行
	 */
	private Map<String, Object> addCitySumRow(String prevAreaId, Table<String, Integer, List<Double>> indicatorValTab,
			List<ReportTypeIndicator> rtis, Map<Integer, Indicator> indicatorMap) {
		String cityAreaId = prevAreaId.substring(0, 4) + StringUtils.repeat("0", 11);
		String cityAreaIdPrefix = prevAreaId.substring(0, 4);
		Area area = areaService.queryAreaById(cityAreaId);
		Map<String, Object> row = Maps.newLinkedHashMap();
		row.put("选择审核", false);
		row.put("企业编号", "");
		row.put("企业名称", area.getAreaName() + "市级总计");
		row.put("unitId", R.UU16());
		row.put(AREA_NAME_KEY, area.getAreaName());
		row.put(AREA_ID_KEY, area.getId());
		int i = 1;
		for (ReportTypeIndicator rti : rtis) {
			Indicator indicator = indicatorMap.get(rti.getIndicatorId());
			if (indicator.getSummarization() == 1) {
				double indicatorSum = sumCityIndicatorVal(indicatorValTab, cityAreaIdPrefix, indicator);
				row.put(indicator.getName() + "/" + indicator.getUnit(), String.format("%.2f", indicatorSum));
				//				row.put(indicator.getName(), String.format("%.2f", indicatorSum));
			} else {
				//				row.put(indicator.getName(), "");
				row.put(indicator.getName() + "/" + indicator.getUnit(), "");
			}
			i++;
		}

		return row;

	}

	/**
	 * 将指标值按市级进行汇总.
	 * 
	 * @param indicatorValTab
	 * @param cityAreaIdPrefix
	 * @param indicator
	 * @return
	 */
	private double sumCityIndicatorVal(Table<String, Integer, List<Double>> indicatorValTab, String cityAreaIdPrefix,
			Indicator indicator) {
		Set<String> areaIds = indicatorValTab.rowKeySet();
		// 当前市级所属的地区id
		Set<String> curCityAreaIds = Sets.newHashSet();
		for (String areaId : areaIds) {
			if (areaId.startsWith(cityAreaIdPrefix)) {
				curCityAreaIds.add(areaId);
			}
		}

		double indicatorSum = 0;
		for (String areaId : curCityAreaIds) {
			List<Double> indicatorVals = indicatorValTab.get(areaId, indicator.getId());
			for (Double indicatorVal : indicatorVals) {
				indicatorSum += indicatorVal;
			}
		}
		return indicatorSum;
	}

	/**
	 * 增加县或市直属合计
	 */
	private Map<String, Object> addAreaSumRow(String prevAreaId, Table<String, Integer, List<Double>> indicatorValTab,
			List<ReportTypeIndicator> rtis, Map<Integer, Indicator> indicatorMap) {
		Area area = areaService.queryAreaById(prevAreaId);
		Map<String, Object> row = Maps.newLinkedHashMap();
		row.put("选择审核", false);
		row.put("企业编号", "");
		row.put("unitId", R.UU16());
		row.put("企业名称", area.getAreaName() + "小计");
		row.put(AREA_NAME_KEY, area.getAreaName());
		row.put(AREA_ID_KEY, area.getId());
		int i = 1;
		for (ReportTypeIndicator rti : rtis) {
			Indicator indicator = indicatorMap.get(rti.getIndicatorId());
			if (indicator.getSummarization() == 1) {
				List<Double> indicatorVals = indicatorValTab.get(prevAreaId, indicator.getId());
				double indicatorSum = 0;
				for (Double indicatorVal : indicatorVals) {
					indicatorSum += indicatorVal;
				}
				row.put(indicator.getName() + "/" + indicator.getUnit(), String.format("%.2f", indicatorSum));
				//				row.put(indicator.getName(), String.format("%.2f", indicatorSum));
			} else {
				row.put(indicator.getName() + "/" + indicator.getUnit(), "");
				//				row.put(indicator.getName(), "");
			}
			i++;
		}

		return row;
	}

	/**
	 * 将行式报表详情转换成单行形式.
	 * 
	 * @param reportDetails
	 * @param reportTypeId
	 */
	public DynamicReportVO converRowReportDetail(List<VerifyReportDetail> reportDetails, SummaryReportType srt,
			String currentUserAreaId, boolean flag) {

		ReportIndicatorInfo rii = getReportIndicatorInfo(srt);

		Set<AreaUnitIdReportId> urids = extractUnitId(reportDetails);
		Table<String, Integer, List<Double>> indicatorValTab = HashBasedTable.create();
		List<Map<String, Object>> table = Lists.newArrayList();

		for (final AreaUnitIdReportId urid : urids) {

			List<VerifyReportDetail> vrds = filterByUnitAndReport(reportDetails, urid.unitId, urid.reportId);
			List<Map<String, Object>> rows = createRowReportRows(rii, indicatorValTab, urid, vrds);
			table.addAll(rows);

		}

		addSumRow(currentUserAreaId, rii.indicatorMap, rii.rtis, urids, table, indicatorValTab);

		return transformResult(flag, rii.indicatorMap, rii.rtis, table);
	}

	private List<Map<String, Object>> createRowReportRows(ReportIndicatorInfo rii,
			Table<String, Integer, List<Double>> indicatorValTab, final AreaUnitIdReportId urid,
			List<VerifyReportDetail> vrds) {
		List<Map<String, Object>> rows = Lists.newArrayList();
		boolean isFirst = true;
		for (VerifyReportDetail vrd : vrds) {
			Map<String, Object> row = Maps.newLinkedHashMap();
			row.put("unitId", urid.unitId);
			row.put("reportId", urid.reportId);
			row.put(AREA_ID_KEY, urid.areaId);
			Unit unit = unitService.queryUnitById(urid.unitId);
			row.put(AREA_NAME_KEY, unit.getArea().getAreaName());
			if (isFirst) {
				row.put("企业编号", unit.getSuperCompanyCode());
				row.put("企业名称", unit.getUnitName());
				row.put("选择审核", true);
				isFirst = false;
			} else {
				row.put("企业编号", "");
				row.put("企业名称", "");
				row.put("选择审核", false);
			}
			int i = 1;
			for (ReportTypeIndicator rti : rii.rtis) {
				String indicatorValue = getIndicatorValue(vrd, rti.getTheColumn());
				Indicator indicator = rii.indicatorMap.get(rti.getIndicatorId());
				//				row.put(indicator.getName(), indicatorValue);
				row.put(indicator.getName() + "/" + indicator.getUnit(), indicatorValue);
				i++;
				if (indicator.getSummarization() == 1) {
					addIndicatorValToTable(indicatorValTab, vrd, indicatorValue, indicator);
				}
			}

			rows.add(row);

		}

		return rows;
	}

	/**
	 * 增加省，市，县合计行
	 * 
	 * @param currentUserAreaId
	 * @param indicatorMap
	 * @param rtis
	 * @param urids
	 * @param table
	 * @param indicatorValTab
	 */
	private void addSumRow(String currentUserAreaId, Map<Integer, Indicator> indicatorMap,
			List<ReportTypeIndicator> rtis, Set<AreaUnitIdReportId> urids, List<Map<String, Object>> table,
			Table<String, Integer, List<Double>> indicatorValTab) {
		// 增加县小计行
		Set<String> areaIds = Sets.newLinkedHashSet();
		for (AreaUnitIdReportId urid : urids) {
			areaIds.add(urid.areaId);
		}
		for (String areaId : areaIds) {
			Map<String, Object> areaSumRow = addAreaSumRow(areaId, indicatorValTab, rtis, indicatorMap);
			table.add(areaSumRow);
		}

		// 增加市级汇总数据
		if (Constants.PROVINCE_AREA_ID.equals(currentUserAreaId)) {
			Set<String> cityIds = Sets.newLinkedHashSet();
			for (AreaUnitIdReportId urid : urids) {
				cityIds.add(getCityId(urid.areaId));
			}

			for (String cityId : cityIds) {
				Map<String, Object> citySumRow = addCitySumRow(cityId, indicatorValTab, rtis, indicatorMap);
				table.add(citySumRow);
			}
		}

		if (isNeedLastSumRow(currentUserAreaId)) {
			// 增加合计总行
			Map<String, Object> totalSumRow = addTotalSumRow(currentUserAreaId, indicatorValTab, rtis, indicatorMap);
			table.add(totalSumRow);
		}
	}

	/**
	 * 获得地区代码对应的市级id.
	 * 
	 * @param areaId
	 * @return
	 */
	private String getCityId(String areaId) {
		String cityId = null;
		if (!Constants.PROVINCE_AREA_ID.equals(areaId)) {
			cityId = StringUtils.rightPad(areaId.substring(0, 4), 15, "0");
		}
		return cityId;
	}

	/**
	 * 将数据转换为父子结构的数据
	 * 
	 * @param hd
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private List<Map<String, Object>> converHdataToGdata(List<Map<String, Object>> hdata) {

		Set<String> uniqueAreaIds = getUniqueAreaIds(hdata);
		String rootAreaId = Sets.newTreeSet(uniqueAreaIds).first();

		Map<String, Area> uniqueArea = getUniqueArea(uniqueAreaIds);

		List<Map<String, Object>> pdataTemp = Lists.newArrayList();
		for (String areaId : uniqueAreaIds) {
			Map<String, Object> row = Maps.newHashMap();
			row.put(AREA_ID_KEY, areaId);
			Area area = uniqueArea.get(areaId);
			row.put(AREA_NAME_KEY, area.getAreaName());
			row.put("unitId", R.UU16());
			List<Object> children = Lists.newArrayList();
			for (Map<String, Object> d : hdata) {
				String dataAreaId = (String) d.get(AREA_ID_KEY);
				if (dataAreaId.equals(areaId)) {
					children.add(d);
				}
			}

			row.put("children", children);
			pdataTemp.add(row);
		}

		List<Map<String, Object>> pdata = Lists.newArrayList();

		for (Map<String, Object> row : pdataTemp) {
			String areaId = (String) row.get(AREA_ID_KEY);
			Area area = uniqueArea.get(areaId);
			if (rootAreaId.equals(areaId)) {
				pdata.add(row);
			} else {

				for (Map<String, Object> row1 : pdataTemp) {
					String key = (String) row1.get(AREA_ID_KEY);
					if (key.equals(area.getParentId())) {
						List child = (List) row1.get("children");
						child.add(0, row);
						break;
					}
				}
			}
		}

		return pdata;
	}

	private Set<String> getUniqueAreaIds(List<Map<String, Object>> hdata) {
		Set<String> uniqueAreaIds = Sets.newLinkedHashSet();
		for (Map<String, Object> row : hdata) {
			String areaId = (String) row.get(AREA_ID_KEY);
			uniqueAreaIds.add(areaId);
		}
		return uniqueAreaIds;
	}

	private Map<String, Area> getUniqueArea(Set<String> areaIds) {
		Map<String, Area> areas = Maps.newLinkedHashMap();
		for (String areaId : areaIds) {
			Area area = areaService.queryAreaById(areaId);
			areas.put(areaId, area);
		}

		return areas;
	}

	private Map<Integer, Indicator> getIndicatorMapByReportType(String reportTypeId) {
		String sql = "SELECT * FROM t_indicator i INNER JOIN t_report_type_indicator rti ON i.id = rti.indicator_id AND rti.report_type_id = @reportTypeId";
		List<Indicator> indicators = sqlTemplate
				.query(sql, Collections.<String, Object> singletonMap("reportTypeId", reportTypeId),
						dao.getEntity(Indicator.class));
		return Maps.uniqueIndex(indicators, new Function<Indicator, Integer>() {
			@Override
			public Integer apply(Indicator input) {
				return input.getId();
			}
		});
	}

	/**
	 * 根据单位id，报表id，行号索引对报表记录详情进行过滤.
	 * 
	 * @param reportDetails
	 * @param unitId
	 * @param rowIndex
	 * @return
	 */
	private VerifyReportDetail filterByUnitAndReportAndRow(List<VerifyReportDetail> reportDetails, final String unitId,
			final String reportId, final int rowIndex) {
		Collection<VerifyReportDetail> filterResults = Collections2.filter(reportDetails,
				new Predicate<VerifyReportDetail>() {

					@Override
					public boolean apply(VerifyReportDetail input) {
						boolean unitIsEqual = unitId.equals(input.getUnitId());
						boolean reportIsEqual = reportId.equals(input.getReportId());
						boolean rowIsEqual = input.getRowIndex() == rowIndex;
						return unitIsEqual && reportIsEqual && rowIsEqual;
					}

				});
		return filterResults.iterator().next();
	}

	/**
	 * 根据单位id，报表id，行号索引对报表记录详情进行过滤.
	 * 
	 * @param reportDetails
	 * @param unitId
	 * @param rowIndex
	 * @return
	 */
	private List<VerifyReportDetail> filterByUnitAndReport(List<VerifyReportDetail> reportDetails, final String unitId,
			final String reportId) {
		Collection<VerifyReportDetail> filterResults = Collections2.filter(reportDetails,
				new Predicate<VerifyReportDetail>() {

					@Override
					public boolean apply(VerifyReportDetail input) {
						boolean unitIsEqual = unitId.equals(input.getUnitId());
						boolean reportIsEqual = reportId.equals(input.getReportId());
						return unitIsEqual && reportIsEqual;
					}

				});
		return Lists.newArrayList(filterResults);
	}

	/**
	 * 抽取指标值.
	 * 
	 * @param reportDetail
	 * @param indicatorColumnIndex
	 * @return
	 */
	private String getIndicatorValue(VerifyReportDetail reportDetail, int indicatorColumnIndex) {
		String indicatorValue = null;
		try {
			String fieldName = String.format("f%d", indicatorColumnIndex);
			indicatorValue = (String) mirror.getValue(reportDetail, fieldName);
		} catch (Exception e) {
			indicatorValue = null;
		}
		return indicatorValue;
	}

	private Set<AreaUnitIdReportId> extractUnitId(List<VerifyReportDetail> reportDetails) {
		List<AreaUnitIdReportId> unitIds = Lists.transform(reportDetails,
				new Function<VerifyReportDetail, AreaUnitIdReportId>() {
					@Override
					public AreaUnitIdReportId apply(VerifyReportDetail input) {
						return new AreaUnitIdReportId(input.getAeraId(), input.getUnitId(), input.getReportId());
					}

				});

		return Sets.newLinkedHashSet(unitIds);
	}

	/**
	 * 单位id报表id
	 */
	class AreaUnitIdReportId {
		String areaId;
		String unitId;
		String reportId;

		public AreaUnitIdReportId(String areaId, String unitId, String reportId) {
			this.areaId = areaId;
			this.unitId = unitId;
			this.reportId = reportId;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + getOuterType().hashCode();
			result = prime * result + ((areaId == null) ? 0 : areaId.hashCode());
			result = prime * result + ((reportId == null) ? 0 : reportId.hashCode());
			result = prime * result + ((unitId == null) ? 0 : unitId.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			AreaUnitIdReportId other = (AreaUnitIdReportId) obj;
			if (!getOuterType().equals(other.getOuterType())) {
				return false;
			}
			if (areaId == null) {
				if (other.areaId != null) {
					return false;
				}
			} else if (!areaId.equals(other.areaId)) {
				return false;
			}
			if (reportId == null) {
				if (other.reportId != null) {
					return false;
				}
			} else if (!reportId.equals(other.reportId)) {
				return false;
			}
			if (unitId == null) {
				if (other.unitId != null) {
					return false;
				}
			} else if (!unitId.equals(other.unitId)) {
				return false;
			}
			return true;
		}

		private SummaryReportService getOuterType() {
			return SummaryReportService.this;
		}

	}
}
